﻿module Lab3_4
open System.Collections.Generic
let X t = fst t
let Y t = snd t

let borders lst x =
  try
    let highIndex = List.findIndex (fun k -> x <= (X k)) lst
    if highIndex < 1 || highIndex > (lst.Length-2) then
      raise <| new System.ArgumentOutOfRangeException()
    let nth = List.nth lst
    nth (highIndex-1), nth highIndex, nth (highIndex+1)
  with
  | :? KeyNotFoundException -> raise <| new System.ArgumentOutOfRangeException()

let subdiv fraction = 
  let (x:float,y), (x',y') = fraction
  (y' - y) / (x' - x)

let derivative table x f =
  let i, i1, i2 = borders table x
  let g_i = (subdiv (i, i1))
  let g_i1 = (subdiv (i1, i2))
  f i i1 i2 g_i g_i1

let (!) table x =
  derivative table x (fun i i1 i2 g_i g_i1 ->
  g_i + ((g_i1 - g_i) / (X(i2) - X(i))) * (2.0 * x - X(i) - X(i1)))
  
let (!!) table x =
  derivative table x (fun i i1 i2 g_i g_i1 ->
  2.0 * ((g_i1 - g_i) / (X(i2) - X(i))))

let lab =
  printfn "Lab 3.4"
  let lst = [(-1.0,-1.7854);
            (0.0,0.0);
            (1.0, 1.7854);
            (2.0, 3.1071);
            (3.0, 4.249)]

  let f', f'' = !lst, !!lst
  printfn "F'(1.0): %f\nF''(1.0): %f" (f' 1.0) (f'' 1.0)
  printfn "======="